package com.jdrx.ocp.api;

import com.jdrx.ocp.beans.constans.EUserStatus;
import com.jdrx.ocp.beans.constans.EventActionEnum;
import com.jdrx.ocp.beans.constans.EventEnum;
import com.jdrx.ocp.beans.dto.DeleteBaseDTO;
import com.jdrx.ocp.beans.dto.dept.QueryByIdsDTO;
import com.jdrx.ocp.beans.dto.login.LogoutDTO;
import com.jdrx.ocp.beans.dto.resource.QueryResourceTreeDTO;
import com.jdrx.ocp.beans.dto.user.*;
import com.jdrx.ocp.beans.event.NoticesEvent;
import com.jdrx.ocp.beans.vo.QueryUserVO;
import com.jdrx.ocp.beans.vo.UserOptionVO;
import com.jdrx.ocp.beans.vo.UserVO;
import com.jdrx.ocp.service.AdminService;
import com.jdrx.ocp.service.NoticeEventService;
import com.jdrx.ocp.service.ResourceService;
import com.jdrx.ocp.service.UserService;
import com.jdrx.ocp.utils.Constants;
import com.jdrx.platform.common.support.gateway.GwConstants;
import com.jdrx.platform.commons.rest.beans.dto.IdDTO;
import com.jdrx.platform.commons.rest.beans.enums.EApiStatus;
import com.jdrx.platform.commons.rest.beans.vo.ResponseVO;
import com.jdrx.platform.commons.rest.beans.vo.ResposeVO;
import com.jdrx.platform.commons.rest.exception.BizException;
import com.jdrx.platform.commons.rest.factory.ResponseFactory;
import com.jdrx.platform.commons.rest.factory.ResponseFactory2;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
import java.util.Optional;

import static com.jdrx.platform.common.support.gateway.GwConstants.TRANSPARENT_USERID_FEILD;

@RestController
@RequestMapping("/api/0/user/")
@Api(value = "用户管理")
public class UserApi {
    @Autowired
    private UserService userService;
    @Autowired
    private NoticeEventService noticeEventService;
    @Autowired
    private AdminService adminService;
    @Autowired
    private ResourceService resourceService;

    @ApiOperation("用户列表")
    @PostMapping("list")
    public <T> ResponseVO<List<UserVO>> list(@RequestBody @Valid QueryUserDTO dto) throws BizException {
        return ResponseFactory2.ok(userService.list(dto));
    }

    @ApiOperation("用户列表，用于下拉框或其他选项")
    @PostMapping("optionList")
    public <T> ResponseVO<List<UserOptionVO>> optionList() throws BizException {
        return ResponseFactory2.ok(userService.optionList());
    }

    @ApiOperation("新增用户")
    @PostMapping("add")
    public <T> ResponseVO<T> add(@RequestHeader(GwConstants.TRANSPARENT_USERID_FEILD) Long uid,
                                 @RequestHeader(GwConstants.TRANSPARENT_TENANT_ID) Long tenantId,
                                 @RequestHeader(GwConstants.TRANSPARENT_DATA_NODE) String dataNode,
                                 @RequestBody @Valid AddUserDTO dto,
                                 BindingResult result) throws Exception {
        if (result.hasErrors()) {
            return ResponseFactory2.err(EApiStatus.ERR_VALIDATE.getStatus(), result.getFieldErrors().get(0).getField() + result.getAllErrors().get(0).getDefaultMessage());
        }
        dto.setCreateBy(uid);
        dto.setTenantId(tenantId);
        dto.setDataNode(dataNode);
        userService.add(dto);
        return ResponseFactory2.ok();
    }

    @ApiOperation("修改用户")
    @PostMapping("update")
    public <T> ResponseVO<T> update(@RequestHeader(TRANSPARENT_USERID_FEILD) Long uid,
                                    @RequestBody @Valid UpdateUserDTO dto,
                                    BindingResult result) throws BizException {
        if (result.hasErrors()) {
            return ResponseFactory2.err(EApiStatus.ERR_VALIDATE.getStatus(), result.getFieldErrors().get(0).getField() + result.getAllErrors().get(0).getDefaultMessage());
        }
        dto.setUpdateBy(uid);
        userService.update(dto);
        return ResponseFactory2.ok();
    }

    @ApiOperation("删除用户")
    @PostMapping("delete")
    public <T> ResponseVO<T> delete(@RequestHeader(TRANSPARENT_USERID_FEILD) Long uid,
                                    @RequestBody @Valid DeleteBaseDTO dto) throws BizException {
        dto.setUpdateBy(uid);
        userService.delete(dto);
        return ResponseFactory2.ok();
    }

    @ApiOperation("修改密码")
    @PostMapping("updatePwd")
    public <T> ResponseVO<T> updatePwd(@RequestHeader(TRANSPARENT_USERID_FEILD) Long uid,
                                       @RequestBody @Valid UpdateUserPwdDTO dto) throws BizException {
        userService.updatePwd(dto);
        return ResponseFactory2.ok();
    }

    @ApiOperation("修改用户关注数据卡片配置")
    @PostMapping("updateFollowCards")
    public <T> ResponseVO<T> updatePwd(@RequestHeader(TRANSPARENT_USERID_FEILD) Long uid,
                                       @RequestBody @Valid UpdateFollowCardsDTO dto) throws BizException {
        dto.setId(uid);
        userService.updateFollowCards(dto);
        return ResponseFactory2.ok();
    }

    @RequestMapping(value = "whiteList", method = RequestMethod.POST)
    @ApiOperation(value = "查询白名单用户", notes = "根据条件查询用户信息并分页")
    public ResposeVO queryWhiteList(@ApiParam(required = true)
                                    @RequestBody @Valid QueryUserWithStatusDTO dto,
                                    @RequestHeader(value = Constants.TENANT_ID, required = false, defaultValue = "") String tid) throws BizException {
        dto.setStatus(EUserStatus.NORMAL.code);
        return ResponseFactory.ok(userService.queryUserByStatus(dto, tid));
    }

    @RequestMapping(value = "blackList", method = RequestMethod.POST)
    @ApiOperation(value = "查询黑名单用户", notes = "根据条件查询用户信息并分页")
    public ResposeVO queryBlackList(@ApiParam(required = true)
                                    @RequestBody @Valid QueryUserWithStatusDTO dto,
                                    @RequestHeader(value = Constants.TENANT_ID, required = false, defaultValue = "") String tid) throws BizException {
        dto.setStatus(EUserStatus.DISABLE.code);
        return ResponseFactory.ok(userService.queryUserByStatus(dto, tid));
    }

	/*@RequestMapping(value = "queryUserByPage", method = RequestMethod.POST)
	@ApiOperation(value = "用户查询", notes = "根据条件查询用户信息并分页")
	public ResposeVO queryUserByPage(@ApiParam(required = true) @RequestBody @Valid QueryUserDTO queryUserDTO) throws BizException {
	    queryUserDTO.setName(Optional.ofNullable(queryUserDTO.getName()).orElse(null));
	    queryUserDTO.setRealName(Optional.ofNullable(queryUserDTO.getRealName()).orElse(null));
	    return ResponseFactory.ok(userService.queryUserByPage(queryUserDTO));
	}*/

    @RequestMapping(value = "queryUserById", method = RequestMethod.POST)
    @ApiOperation(value = "根据主键查询用户", notes = "根据主键查询用户")
    public ResposeVO queryUserById(@RequestHeader(TRANSPARENT_USERID_FEILD) Long uId,
                                   @RequestBody(required = false) IdDTO<Long> idDTO) throws BizException {
        Long userId = Optional.ofNullable(idDTO).map(idDTO1 -> idDTO1.getId()).orElse(uId);
        QueryUserVO queryUserVO = userService.queryUserById(userId);
        if (queryUserVO == null) {
            return ResponseFactory.err("没有该用户信息", EApiStatus.ERR_SYS);
        }
        return ResponseFactory.ok(queryUserVO);
    }

    @RequestMapping(value = "queryUserByIds", method = RequestMethod.POST)
    @ApiOperation(value = "根据主键集合查询用户", notes = "根据主键集合查询用户")
    public ResposeVO queryUserByIds(@RequestBody(required = true) QueryByIdsDTO queryByIdsDTO) throws BizException {
        return ResponseFactory.ok(userService.queryUserByIds(queryByIdsDTO));
    }

    @RequestMapping(value = "create", method = RequestMethod.POST)
    @ApiOperation(value = "创建用户数据", notes = "添加一条用户数据")
    //@BizLogger(description = "创建用户数据", serviceId = Constants.SERVICE_ID)
    public ResposeVO create(@RequestBody @Valid CreateUserDTO createUserDTO,
                            @RequestHeader(TRANSPARENT_USERID_FEILD) Integer uId,
                            @RequestHeader(value = Constants.TENANT_ID, required = false, defaultValue = "") String tid) throws BizException {
        return ResponseFactory.ok(userService.createUser(createUserDTO, uId, tid));
    }

    @ApiOperation("运营端远程创建超级管理员用户")
    @PostMapping("createAdmin")
    public ResposeVO createAdmin(@RequestBody @Valid CreateAdminUserDTO dto) throws BizException {
        userService.createAdminUser(dto);
        return ResponseFactory.ok("");
    }

    @RequestMapping(value = "updateApp", method = RequestMethod.POST)
    @ApiOperation(value = "更新用户授权产品包", notes = "更新用户授权产品包")
    //@BizLogger(description = "更新用户授权产品包", serviceId = Constants.SERVICE_ID)
    public ResposeVO updateApp(@RequestBody @Valid UpdateAppDTO dto) throws BizException {
        userService.updateApp(dto);
        return ResponseFactory.ok("更新成功");
    }

    @RequestMapping(value = "updateBaseInfo", method = RequestMethod.POST)
    @ApiOperation(value = "更新用户基本数据", notes = "更新用户基本数据")
    //@BizLogger(description = "更新用户基本数据", serviceId = Constants.SERVICE_ID)
    public ResposeVO updateBaseInfo(@RequestBody @Valid UpdateBaseUserDTO updateUserDTO,
                                    @RequestHeader(TRANSPARENT_USERID_FEILD) Integer uId,
                                    @RequestHeader(value = Constants.TENANT_ID, required = false, defaultValue = "") String tid) throws BizException {
        if (userService.updateBaseUser(updateUserDTO, uId, tid) >= 0) {
            return ResponseFactory.ok("操作成功");
        } else {
            return ResponseFactory.err("更新用户失败", EApiStatus.ERR_SYS);
        }
    }

    @RequestMapping(value = "updateStatus", method = RequestMethod.POST)
    @ApiOperation(value = "启停用户", notes = "启停用户")
    //@BizLogger(description = "启停用户", serviceId = Constants.SERVICE_ID)
    public ResposeVO updateStatus(@RequestHeader(TRANSPARENT_USERID_FEILD) Integer uId,
                                  @RequestBody @Valid UpdateUserStatusDTO updateUserStatusDTO,
                                  @RequestHeader(value = Constants.TENANT_ID, required = false, defaultValue = "") String tid) throws BizException {
        if (userService.updateUserStatus(updateUserStatusDTO, uId, tid) >= 0) {
            return ResponseFactory.ok("操作成功");
        } else {
            return ResponseFactory.err("更新用户失败", EApiStatus.ERR_SYS);
        }
    }

    @RequestMapping(value = "updatePwdRemote", method = RequestMethod.POST)
    @ApiOperation(value = "运营端更新用户密码", notes = "运营端更新用户密码")
    //@BizLogger(description = "运营端更新用户密码", serviceId = Constants.SERVICE_ID)
    public ResposeVO updatePwdRemote(@RequestBody @Valid UpdateUserPwdRemoteDTO dto) throws BizException {
        userService.updatePwd(dto);
        return ResponseFactory.ok("操作成功");
    }

    @RequestMapping(value = "awardedRole", method = RequestMethod.POST)
    @ApiOperation(value = "分配用户角色权限", notes = "分配用户角色权限")
    //@BizLogger(description = "分配用户角色权限", serviceId = Constants.SERVICE_ID)
    public ResposeVO awardedRole(@RequestBody @Valid UserRoleDTO userRoleDTO) throws BizException {
        if (userService.awardedRole(userRoleDTO)) {
            return ResponseFactory.ok("操作成功");
        } else {
            return ResponseFactory.err("分配角色权限失败", EApiStatus.ERR_SYS);
        }
    }

    @RequestMapping(value = "queryUserRole", method = RequestMethod.POST)
    @ApiOperation(value = "查询用户拥有的角色", notes = "查询用户拥有的角色")
    public ResposeVO queryUserRole(@RequestHeader(TRANSPARENT_USERID_FEILD) Long userId) throws BizException {
        QueryUserRoleDTO queryUserRoleDTO = new QueryUserRoleDTO();
        queryUserRoleDTO.setUserId(userId);
        return ResponseFactory.ok(userService.queryUserRoleAll(queryUserRoleDTO));
    }

    @RequestMapping(value = "queryUserMenu", method = RequestMethod.POST)
    @ApiOperation(value = "获取用户菜单", notes = "获取用户菜单")
    public ResposeVO queryUserMenu(@RequestBody @Valid QueryUserMenuDTO queryUserMenuDTO,
                                   @RequestHeader(TRANSPARENT_USERID_FEILD) Long userId,
                                   @RequestHeader(value = Constants.TENANT_ID, required = false, defaultValue = "") String tid) throws BizException {
        QueryUserResourceDTO queryUserResourceDTO = new QueryUserResourceDTO();
        queryUserResourceDTO.setUserId(userId);
        queryUserResourceDTO.setPrefix(queryUserMenuDTO.getPrefix());
        return ResponseFactory.ok(userService.queryUserResource(queryUserResourceDTO, tid));
    }

    @RequestMapping(value = "queryUserMenuForTree", method = RequestMethod.POST)
    @ApiOperation(value = "获取用户菜单（树结构）", notes = "获取用户菜单（树结构）")
    public ResposeVO queryUserMenuForTree(@RequestBody @Valid QueryUserMenuDTO queryUserMenuDTO,
                                          @RequestHeader(TRANSPARENT_USERID_FEILD) Long userId,
                                          @RequestHeader(value = Constants.TENANT_ID, required = false, defaultValue = "") String tid) throws BizException {
        QueryUserResourceDTO queryUserResourceDTO = new QueryUserResourceDTO();
        queryUserResourceDTO.setUserId(userId);
        queryUserResourceDTO.setPrefix(queryUserMenuDTO.getPrefix());
        return ResponseFactory.ok(userService.listToTree(userService.queryUserResource(queryUserResourceDTO, tid), 0L));
    }

    @RequestMapping(value = "queryMenuByIdsForTree", method = RequestMethod.POST)
    @ApiOperation(value = "获取指定菜单（树结构）", notes = "获取指定菜单（树结构）")
    public ResposeVO queryMenuByIdsForTree(@RequestBody @Valid QueryUserMenuDTO queryUserMenuDTO,
                                           @RequestHeader(TRANSPARENT_USERID_FEILD) Long userId,
                                           @RequestHeader(value = Constants.TENANT_ID, required = false, defaultValue = "") String tid) throws BizException {
        QueryUserResourceDTO queryUserResourceDTO = new QueryUserResourceDTO();
        queryUserResourceDTO.setUserId(userId);
        queryUserResourceDTO.setPrefix(queryUserMenuDTO.getPrefix());
        queryUserResourceDTO.setResourceIds(queryUserMenuDTO.getResourceIds());
        return ResponseFactory.ok(userService.listToTree(userService.queryResourceByIds(queryUserResourceDTO, tid), 0L));
    }

    @RequestMapping(value = "getUserResource", method = RequestMethod.POST)
    @ApiOperation(value = "获取用户资源数据", notes = "获取用户资源数据,包含所有拥有的资源")
    public ResposeVO getUserResource(@RequestHeader(TRANSPARENT_USERID_FEILD) Long userId) throws BizException {
        QueryUserResourceDTO queryUserResourceDTO = new QueryUserResourceDTO();
        queryUserResourceDTO.setUserId(userId);
        return ResponseFactory.ok(userService.queryUserAllResource(queryUserResourceDTO));
    }


    @RequestMapping(value = "getUserService", method = RequestMethod.POST)
    @ApiOperation(value = "获取用户拥有的服务", notes = "获取用户拥有的服务")
    public ResposeVO getUserService(@RequestHeader(TRANSPARENT_USERID_FEILD) Integer userId) throws BizException {
        return ResponseFactory.ok(userService.getUserResourceService(userId));
    }

    @RequestMapping(value = "getGroupUserService", method = RequestMethod.POST)
    @ApiOperation(value = "获取分组后的用户服务", notes = "获取分组后的用户服务")
    public ResposeVO getGroupUserService(@RequestHeader(TRANSPARENT_USERID_FEILD) Integer userId,
                                         @RequestHeader(value = Constants.TENANT_ID, required = false, defaultValue = "") String tid) throws BizException {
        return ResponseFactory.ok(userService.getGroupUserService(userId, tid));
    }


    @RequestMapping(value = "queryUserByToken", method = RequestMethod.POST)
    @ApiOperation(value = "根据TOKEN查询用户", notes = "根据TOKEN查询用户")
    public ResposeVO queryUserByToken(@RequestHeader(TRANSPARENT_USERID_FEILD) Long userId) throws BizException {
        return ResponseFactory.ok(userService.queryUserByToken(userId));
    }

    @RequestMapping(value = "getUserLikeCodeOrName", method = RequestMethod.POST)
    @ApiOperation(value = "获取用户ID集", notes = "获取用户ID集")
    public ResposeVO getUserLikeCodeOrName(@RequestBody @Valid QueryUserLikeNameDTO queryUserLikeNameDTO) throws BizException {
        return ResponseFactory.ok(userService.getUserLikeCodeOrName(queryUserLikeNameDTO.getName(), queryUserLikeNameDTO.getId()));
    }

    @RequestMapping(value = "getPrivateKey", method = RequestMethod.POST)
    @ApiOperation(value = "获取用户明文密钥", notes = "根据用户ID获取用户明文密钥")
    public ResposeVO getPrivateKey(@RequestHeader(TRANSPARENT_USERID_FEILD) Long id) throws BizException {
        return ResponseFactory.ok(userService.getPrivateKey(id));
    }

    @RequestMapping(value = "passwordRule", method = RequestMethod.POST)
    @ApiOperation(value = "密码安全策略规则", notes = "密码安全策略规则")
    public ResposeVO passwordRule(@RequestHeader(value = Constants.TENANT_ID, required = false, defaultValue = "") String tid) throws BizException {
        return ResponseFactory.ok(userService.passwordRule(tid));
    }

    @RequestMapping(value = "storageRedis", method = RequestMethod.POST)
    @ApiOperation(value = "缓存用户信息", notes = "缓存用户信息")
    public ResposeVO storageRedis(@RequestHeader(value = Constants.TENANT_ID, required = false, defaultValue = "") String tid) throws BizException {
        userService.storageRedisUser(tid);
        return ResponseFactory.ok("ok");
    }


    @ApiOperation(value = "退出登陆", notes = "退出登陆")
    @RequestMapping(value = "logout", method = RequestMethod.POST)
    //@BizLogger(description = "用户退出登录", serviceId = SysConstant.APPLICATION_NAME)
    public ResposeVO logout(@RequestHeader(TRANSPARENT_USERID_FEILD) Long userId,
                            @RequestBody(required = false) LogoutDTO logoutDTO,
                            HttpServletRequest request,
                            @RequestHeader(value = Constants.TENANT_ID, required = false) Long tid) {
        noticeEventService.publishEvent(new NoticesEvent(this, EventEnum.LOGOUT, EventActionEnum.LOGOUT, String.valueOf(userId)));
        adminService.logout(userId, request, tid);
        return ResponseFactory.ok(true);
    }

    @RequestMapping(value = "getOperationsMenu", method = RequestMethod.POST)
    @ApiOperation(value = "获取运维菜单", notes = "获取运维菜单")
    public ResposeVO getOperationsMenu(@RequestHeader(TRANSPARENT_USERID_FEILD) Integer uId,
                                       @RequestHeader(value = Constants.TENANT_ID, required = false, defaultValue = "") String tid) throws BizException {
        QueryResourceTreeDTO queryResourceTreeDTO = new QueryResourceTreeDTO();
        queryResourceTreeDTO.setPrefix("ywpf");
        return ResponseFactory.ok(resourceService.getOperationsMenu(uId, queryResourceTreeDTO, tid));
    }


    @RequestMapping(value = "authClassToUser", method = RequestMethod.POST)
    @ApiOperation(value = "文档分类授权", notes = "文档分类授权")
    public ResposeVO authClassToUser(@RequestHeader(TRANSPARENT_USERID_FEILD) Integer userId,
                                     @RequestBody @Valid AuthClassToUserDTO dto,
                                     @RequestHeader(value = Constants.TENANT_ID, required = false, defaultValue = "") String tid) throws BizException {
        userService.authClassToUser(dto, userId, tid);
        return ResponseFactory.ok(EApiStatus.SUCCESS);
    }

    @RequestMapping(value = "getCurrentUser", method = RequestMethod.POST)
    @ApiOperation(value = "获取当前登录用户信息", notes = "获取当前登录用户信息")
    public ResposeVO getCurrentUser(@RequestHeader(TRANSPARENT_USERID_FEILD) Long userId) throws BizException {
        return ResponseFactory.ok(userService.getCurrentUser(userId));
    }


    @RequestMapping(value = "findUserByDeptId", method = RequestMethod.POST)
    @ApiOperation(value = "通过部门id查询人或者负责人", notes = "通过部门id查询人或者负责人")
    public ResposeVO findUserByDeptId(@RequestBody @Valid ChairManUserDTO dto) throws BizException {
        return ResponseFactory.ok(userService.findUserByDeptId(dto));
    }

    @RequestMapping(value = "queryUsersListByDeptId", method = RequestMethod.POST)
    @ApiOperation(value = "查询指定机构部门及其子部门的所有用户列表", notes = "查询指定机构部门及其子部门的所有用户列表")
    public ResposeVO queryUsersListByDeptId(@RequestBody @Valid QueryUserByDeptIdDTO dto) throws BizException {
        return ResponseFactory.ok(userService.queryUsersListByDeptId(dto));
    }

    @RequestMapping(value = "queryUserByDeptId", method = RequestMethod.POST)
    @ApiOperation(value = "查询指定机构部门下的直属用户列表", notes = "查询指定机构部门下的直属用户列表")
    public ResposeVO queryUserByDeptId(@RequestBody @Valid IdDTO<Long> idDTO) throws BizException {
        return ResponseFactory.ok(userService.queryUserByDeptId(idDTO.getId()));
    }
}